home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / a_utils / yacc / byacc / byacc.lha / output.c < prev    next >
C/C++ Source or Header  |  1993-02-22  |  23KB  |  1,211 lines

  1. #include "defs.h"
  2.  
  3. static int nvectors;
  4. static int nentries;
  5. static short **froms;
  6. static short **tos;
  7. static short *tally;
  8. static short *width;
  9. static short *state_count;
  10. static short *order;
  11. static short *base;
  12. static short *pos;
  13. static int maxtable;
  14. static short *table;
  15. static short *check;
  16. static int lowzero;
  17. static int high;
  18.  
  19.  
  20. output()
  21. {
  22.     free_itemsets();
  23.     free_shifts();
  24.     free_reductions();
  25.     output_prefix();
  26.     output_stored_text();
  27.     output_defines();
  28.     output_rule_data();
  29.     output_yydefred();
  30.     output_actions();
  31.     free_parser();
  32.     output_debug();
  33.     output_stype();
  34.     if (rflag) write_section(tables);
  35.     write_section(header);
  36.     output_trailing_text();
  37.     write_section(body);
  38.     output_semantic_actions();
  39.     write_section(trailer);
  40. }
  41.  
  42.  
  43. output_prefix()
  44. {
  45.     if (symbol_prefix == NULL)
  46.     symbol_prefix = "yy";
  47.     else
  48.     {
  49.     ++outline;
  50.     fprintf(code_file, "#define yyparse %sparse\n", symbol_prefix);
  51.     ++outline;
  52.     fprintf(code_file, "#define yylex %slex\n", symbol_prefix);
  53.     ++outline;
  54.     fprintf(code_file, "#define yyerror %serror\n", symbol_prefix);
  55.     ++outline;
  56.     fprintf(code_file, "#define yychar %schar\n", symbol_prefix);
  57.     ++outline;
  58.     fprintf(code_file, "#define yyval %sval\n", symbol_prefix);
  59.     ++outline;
  60.     fprintf(code_file, "#define yylval %slval\n", symbol_prefix);
  61.     ++outline;
  62.     fprintf(code_file, "#define yydebug %sdebug\n", symbol_prefix);
  63.     ++outline;
  64.     fprintf(code_file, "#define yynerrs %snerrs\n", symbol_prefix);
  65.     ++outline;
  66.     fprintf(code_file, "#define yyerrflag %serrflag\n", symbol_prefix);
  67.     ++outline;
  68.     fprintf(code_file, "#define yyss %sss\n", symbol_prefix);
  69.     ++outline;
  70.     fprintf(code_file, "#define yyssp %sssp\n", symbol_prefix);
  71.     ++outline;
  72.     fprintf(code_file, "#define yyvs %svs\n", symbol_prefix);
  73.     ++outline;
  74.     fprintf(code_file, "#define yyvsp %svsp\n", symbol_prefix);
  75.     ++outline;
  76.     fprintf(code_file, "#define yylhs %slhs\n", symbol_prefix);
  77.     ++outline;
  78.     fprintf(code_file, "#define yylen %slen\n", symbol_prefix);
  79.     ++outline;
  80.     fprintf(code_file, "#define yydefred %sdefred\n", symbol_prefix);
  81.     ++outline;
  82.     fprintf(code_file, "#define yydgoto %sdgoto\n", symbol_prefix);
  83.     ++outline;
  84.     fprintf(code_file, "#define yysindex %ssindex\n", symbol_prefix);
  85.     ++outline;
  86.     fprintf(code_file, "#define yyrindex %srindex\n", symbol_prefix);
  87.     ++outline;
  88.     fprintf(code_file, "#define yygindex %sgindex\n", symbol_prefix);
  89.     ++outline;
  90.     fprintf(code_file, "#define yytable %stable\n", symbol_prefix);
  91.     ++outline;
  92.     fprintf(code_file, "#define yycheck %scheck\n", symbol_prefix);
  93.     ++outline;
  94.     fprintf(code_file, "#define yyname %sname\n", symbol_prefix);
  95.     ++outline;
  96.     fprintf(code_file, "#define yyrule %srule\n", symbol_prefix);
  97.     }
  98.     ++outline;
  99.     fprintf(code_file, "#define YYPREFIX \"%s\"\n", symbol_prefix);
  100. }
  101.  
  102.  
  103. output_rule_data()
  104. {
  105.     register int i;
  106.     register int j;
  107.  
  108.   
  109.     fprintf(output_file, "short %slhs[] = {%42d,", symbol_prefix,
  110.         symbol_value[start_symbol]);
  111.  
  112.     j = 10;
  113.     for (i = 3; i < nrules; i++)
  114.     {
  115.     if (j >= 10)
  116.     {
  117.         if (!rflag) ++outline;
  118.         putc('\n', output_file);
  119.         j = 1;
  120.     }
  121.         else
  122.         ++j;
  123.  
  124.         fprintf(output_file, "%5d,", symbol_value[rlhs[i]]);
  125.     }
  126.     if (!rflag) outline += 2;
  127.     fprintf(output_file, "\n};\n");
  128.  
  129.     fprintf(output_file, "short %slen[] = {%42d,", symbol_prefix, 2);
  130.  
  131.     j = 10;
  132.     for (i = 3; i < nrules; i++)
  133.     {
  134.     if (j >= 10)
  135.     {
  136.         if (!rflag) ++outline;
  137.         putc('\n', output_file);
  138.         j = 1;
  139.     }
  140.     else
  141.       j++;
  142.  
  143.         fprintf(output_file, "%5d,", rrhs[i + 1] - rrhs[i] - 1);
  144.     }
  145.     if (!rflag) outline += 2;
  146.     fprintf(output_file, "\n};\n");
  147. }
  148.  
  149.  
  150. output_yydefred()
  151. {
  152.     register int i, j;
  153.  
  154.     fprintf(output_file, "short %sdefred[] = {%39d,", symbol_prefix,
  155.         (defred[0] ? defred[0] - 2 : 0));
  156.  
  157.     j = 10;
  158.     for (i = 1; i < nstates; i++)
  159.     {
  160.     if (j < 10)
  161.         ++j;
  162.     else
  163.     {
  164.         if (!rflag) ++outline;
  165.         putc('\n', output_file);
  166.         j = 1;
  167.     }
  168.  
  169.     fprintf(output_file, "%5d,", (defred[i] ? defred[i] - 2 : 0));
  170.     }
  171.  
  172.     if (!rflag) outline += 2;
  173.     fprintf(output_file, "\n};\n");
  174. }
  175.  
  176.  
  177. output_actions()
  178. {
  179.     nvectors = 2*nstates + nvars;
  180.  
  181.     froms = NEW2(nvectors, short *);
  182.     tos = NEW2(nvectors, short *);
  183.     tally = NEW2(nvectors, short);
  184.     width = NEW2(nvectors, short);
  185.  
  186.     token_actions();
  187.     FREE(lookaheads);
  188.     FREE(LA);
  189.     FREE(LAruleno);
  190.     FREE(accessing_symbol);
  191.  
  192.     goto_actions();
  193.     FREE(goto_map + ntokens);
  194.     FREE(from_state);
  195.     FREE(to_state);
  196.  
  197.     sort_actions();
  198.     pack_table();
  199.     output_base();
  200.     output_table();
  201.     output_check();
  202. }
  203.  
  204.  
  205. token_actions()
  206. {
  207.     register int i, j;
  208.     register int shiftcount, reducecount;
  209.     register int max, min;
  210.     register short *actionrow, *r, *s;
  211.     register action *p;
  212.  
  213.     actionrow = NEW2(2*ntokens, short);
  214.     for (i = 0; i < nstates; ++i)
  215.     {
  216.     if (parser[i])
  217.     {
  218.         for (j = 0; j < 2*ntokens; ++j)
  219.         actionrow[j] = 0;
  220.  
  221.         shiftcount = 0;
  222.         reducecount = 0;
  223.         for (p = parser[i]; p; p = p->next)
  224.         {
  225.         if (p->suppressed == 0)
  226.         {
  227.             if (p->action_code == SHIFT)
  228.             {
  229.             ++shiftcount;
  230.             actionrow[p->symbol] = p->number;
  231.             }
  232.             else if (p->action_code == REDUCE && p->number != defred[i])
  233.             {
  234.             ++reducecount;
  235.             actionrow[p->symbol + ntokens] = p->number;
  236.             }
  237.         }
  238.         }
  239.  
  240.         tally[i] = shiftcount;
  241.         tally[nstates+i] = reducecount;
  242.         width[i] = 0;
  243.         width[nstates+i] = 0;
  244.         if (shiftcount > 0)
  245.         {
  246.         froms[i] = r = NEW2(shiftcount, short);
  247.         tos[i] = s = NEW2(shiftcount, short);
  248.         min = MAXSHORT;
  249.         max = 0;
  250.         for (j = 0; j < ntokens; ++j)
  251.         {
  252.             if (actionrow[j])
  253.             {
  254.             if (min > symbol_value[j])
  255.                 min = symbol_value[j];
  256.             if (max < symbol_value[j])
  257.                 max = symbol_value[j];
  258.             *r++ = symbol_value[j];
  259.             *s++ = actionrow[j];
  260.             }
  261.         }
  262.         width[i] = max - min + 1;
  263.         }
  264.         if (reducecount > 0)
  265.         {
  266.         froms[nstates+i] = r = NEW2(reducecount, short);
  267.         tos[nstates+i] = s = NEW2(reducecount, short);
  268.         min = MAXSHORT;
  269.         max = 0;
  270.         for (j = 0; j < ntokens; ++j)
  271.         {
  272.             if (actionrow[ntokens+j])
  273.             {
  274.             if (min > symbol_value[j])
  275.                 min = symbol_value[j];
  276.             if (max < symbol_value[j])
  277.                 max = symbol_value[j];
  278.             *r++ = symbol_value[j];
  279.             *s++ = actionrow[ntokens+j] - 2;
  280.             }
  281.         }
  282.         width[nstates+i] = max - min + 1;
  283.         }
  284.     }
  285.     }
  286.     FREE(actionrow);
  287. }
  288.  
  289. goto_actions()
  290. {
  291.     register int i, j, k;
  292.  
  293.     state_count = NEW2(nstates, short);
  294.  
  295.     k = default_goto(start_symbol + 1);
  296.     fprintf(output_file, "short %sdgoto[] = {%40d,", symbol_prefix, k);
  297.     save_column(start_symbol + 1, k);
  298.  
  299.     j = 10;
  300.     for (i = start_symbol + 2; i < nsyms; i++)
  301.     {
  302.     if (j >= 10)
  303.     {
  304.         if (!rflag) ++outline;
  305.         putc('\n', output_file);
  306.         j = 1;
  307.     }
  308.     else
  309.         ++j;
  310.  
  311.     k = default_goto(i);
  312.     fprintf(output_file, "%5d,", k);
  313.     save_column(i, k);
  314.     }
  315.  
  316.     if (!rflag) outline += 2;
  317.     fprintf(output_file, "\n};\n");
  318.     FREE(state_count);
  319. }
  320.  
  321. int
  322. default_goto(symbol)
  323. int symbol;
  324. {
  325.     register int i;
  326.     register int m;
  327.     register int n;
  328.     register int default_state;
  329.     register int max;
  330.  
  331.     m = goto_map[symbol];
  332.     n = goto_map[symbol + 1];
  333.  
  334.     if (m == n) return (0);
  335.  
  336.     for (i = 0; i < nstates; i++)
  337.     state_count[i] = 0;
  338.  
  339.     for (i = m; i < n; i++)
  340.     state_count[to_state[i]]++;
  341.  
  342.     max = 0;
  343.     default_state = 0;
  344.     for (i = 0; i < nstates; i++)
  345.     {
  346.     if (state_count[i] > max)
  347.     {
  348.         max = state_count[i];
  349.         default_state = i;
  350.     }
  351.     }
  352.  
  353.     return (default_state);
  354. }
  355.  
  356.  
  357.  
  358. save_column(symbol, default_state)
  359. int symbol;
  360. int default_state;
  361. {
  362.     register int i;
  363.     register int m;
  364.     register int n;
  365.     register short *sp;
  366.     register short *sp1;
  367.     register short *sp2;
  368.     register int count;
  369.     register int symno;
  370.  
  371.     m = goto_map[symbol];
  372.     n = goto_map[symbol + 1];
  373.  
  374.     count = 0;
  375.     for (i = m; i < n; i++)
  376.     {
  377.     if (to_state[i] != default_state)
  378.         ++count;
  379.     }
  380.     if (count == 0) return;
  381.  
  382.     symno = symbol_value[symbol] + 2*nstates;
  383.  
  384.     froms[symno] = sp1 = sp = NEW2(count, short);
  385.     tos[symno] = sp2 = NEW2(count, short);
  386.  
  387.     for (i = m; i < n; i++)
  388.     {
  389.     if (to_state[i] != default_state)
  390.     {
  391.         *sp1++ = from_state[i];
  392.         *sp2++ = to_state[i];
  393.     }
  394.     }
  395.  
  396.     tally[symno] = count;
  397.     width[symno] = sp1[-1] - sp[0] + 1;
  398. }
  399.  
  400. sort_actions()
  401. {
  402.   register int i;
  403.   register int j;
  404.   register int k;
  405.   register int t;
  406.   register int w;
  407.  
  408.   order = NEW2(nvectors, short);
  409.   nentries = 0;
  410.  
  411.   for (i = 0; i < nvectors; i++)
  412.     {
  413.       if (tally[i] > 0)
  414.     {
  415.       t = tally[i];
  416.       w = width[i];
  417.       j = nentries - 1;
  418.  
  419.       while (j >= 0 && (width[order[j]] < w))
  420.         j--;
  421.  
  422.       while (j >= 0 && (width[order[j]] == w) && (tally[order[j]] < t))
  423.         j--;
  424.  
  425.       for (k = nentries - 1; k > j; k--)
  426.         order[k + 1] = order[k];
  427.  
  428.       order[j + 1] = i;
  429.       nentries++;
  430.     }
  431.     }
  432. }
  433.  
  434.  
  435. pack_table()
  436. {
  437.     register int i;
  438.     register int place;
  439.     register int state;
  440.  
  441.     base = NEW2(nvectors, short);
  442.     pos = NEW2(nentries, short);
  443.  
  444.     maxtable = 1000;
  445.     table = NEW2(maxtable, short);
  446.     check = NEW2(maxtable, short);
  447.  
  448.     lowzero = 0;
  449.     high = 0;
  450.  
  451.     for (i = 0; i < maxtable; i++)
  452.     check[i] = -1;
  453.  
  454.     for (i = 0; i < nentries; i++)
  455.     {
  456.     state = matching_vector(i);
  457.  
  458.     if (state < 0)
  459.         place = pack_vector(i);
  460.     else
  461.         place = base[state];
  462.  
  463.     pos[i] = place;
  464.     base[order[i]] = place;
  465.     }
  466.  
  467.     for (i = 0; i < nvectors; i++)
  468.     {
  469.     if (froms[i])
  470.         FREE(froms[i]);
  471.     if (tos[i])
  472.         FREE(tos[i]);
  473.     }
  474.  
  475.     FREE(froms);
  476.     FREE(tos);
  477.     FREE(pos);
  478. }
  479.  
  480.  
  481. /*  The function matching_vector determines if the vector specified by    */
  482. /*  the input parameter matches a previously considered    vector.  The    */
  483. /*  test at the start of the function checks if the vector represents    */
  484. /*  a row of shifts over terminal symbols or a row of reductions, or a    */
  485. /*  column of shifts over a nonterminal symbol.  Berkeley Yacc does not    */
  486. /*  check if a column of shifts over a nonterminal symbols matches a    */
  487. /*  previously considered vector.  Because of the nature of LR parsing    */
  488. /*  tables, no two columns can match.  Therefore, the only possible    */
  489. /*  match would be between a row and a column.  Such matches are    */
  490. /*  unlikely.  Therefore, to save time, no attempt is made to see if a    */
  491. /*  column matches a previously considered vector.            */
  492. /*                                    */
  493. /*  Matching_vector is poorly designed.  The test could easily be made    */
  494. /*  faster.  Also, it depends on the vectors being in a specific    */
  495. /*  order.                                */
  496.  
  497. int
  498. matching_vector(vector)
  499. int vector;
  500. {
  501.     register int i;
  502.     register int j;
  503.     register int k;
  504.     register int t;
  505.     register int w;
  506.     register int match;
  507.     register int prev;
  508.  
  509.     i = order[vector];
  510.     if (i >= 2*nstates)
  511.     return (-1);
  512.  
  513.     t = tally[i];
  514.     w = width[i];
  515.  
  516.     for (prev = vector - 1; prev >= 0; prev--)
  517.     {
  518.     j = order[prev];
  519.     if (width[j] != w || tally[j] != t)
  520.         return (-1);
  521.  
  522.     match = 1;
  523.     for (k = 0; match && k < t; k++)
  524.     {
  525.         if (tos[j][k] != tos[i][k] || froms[j][k] != froms[i][k])
  526.         match = 0;
  527.     }
  528.  
  529.     if (match)
  530.         return (j);
  531.     }
  532.  
  533.     return (-1);
  534. }
  535.  
  536.  
  537.  
  538. int
  539. pack_vector(vector)
  540. int vector;
  541. {
  542.     register int i, j, k, l;
  543.     register int t;
  544.     register int loc;
  545.     register int ok;
  546.     register short *from;
  547.     register short *to;
  548.     int newmax;
  549.  
  550.     i = order[vector];
  551.     t = tally[i];
  552.     assert(t);
  553.  
  554.     from = froms[i];
  555.     to = tos[i];
  556.  
  557.     j = lowzero - from[0];
  558.     for (k = 1; k < t; ++k)
  559.     if (lowzero - from[k] > j)
  560.         j = lowzero - from[k];
  561.     for (;; ++j)
  562.     {
  563.     if (j == 0)
  564.         continue;
  565.     ok = 1;
  566.     for (k = 0; ok && k < t; k++)
  567.     {
  568.         loc = j + from[k];
  569.         if (loc >= maxtable)
  570.         {
  571.         if (loc >= MAXTABLE)
  572.             fatal("maximum table size exceeded");
  573.  
  574.         newmax = maxtable;
  575.         do { newmax += 200; } while (newmax <= loc);
  576.         table = (short *) REALLOC(table, newmax*sizeof(short));
  577.         if (table == 0) no_space();
  578.         check = (short *) REALLOC(check, newmax*sizeof(short));
  579.         if (check == 0) no_space();
  580.         for (l  = maxtable; l < newmax; ++l)
  581.         {
  582.             table[l] = 0;
  583.             check[l] = -1;
  584.         }
  585.         maxtable = newmax;
  586.         }
  587.  
  588.         if (check[loc] != -1)
  589.         ok = 0;
  590.     }
  591.     for (k = 0; ok && k < vector; k++)
  592.     {
  593.         if (pos[k] == j)
  594.         ok = 0;
  595.     }
  596.     if (ok)
  597.     {
  598.         for (k = 0; k < t; k++)
  599.         {
  600.         loc = j + from[k];
  601.         table[loc] = to[k];
  602.         check[loc] = from[k];
  603.         if (loc > high) high = loc;
  604.         }
  605.  
  606.         while (check[lowzero] != -1)
  607.         ++lowzero;
  608.  
  609.         return (j);
  610.     }
  611.     }
  612. }
  613.  
  614.  
  615.  
  616. output_base()
  617. {
  618.     register int i, j;
  619.  
  620.     fprintf(output_file, "short %ssindex[] = {%39d,", symbol_prefix, base[0]);
  621.  
  622.     j = 10;
  623.     for (i = 1; i < nstates; i++)
  624.     {
  625.     if (j >= 10)
  626.     {
  627.         if (!rflag) ++outline;
  628.         putc('\n', output_file);
  629.         j = 1;
  630.     }
  631.     else
  632.         ++j;
  633.  
  634.     fprintf(output_file, "%5d,", base[i]);
  635.     }
  636.  
  637.     if (!rflag) outline += 2;
  638.     fprintf(output_file, "\n};\nshort %srindex[] = {%39d,", symbol_prefix,
  639.         base[nstates]);
  640.  
  641.     j = 10;
  642.     for (i = nstates + 1; i < 2*nstates; i++)
  643.     {
  644.     if (j >= 10)
  645.     {
  646.         if (!rflag) ++outline;
  647.         putc('\n', output_file);
  648.         j = 1;
  649.     }
  650.     else
  651.         ++j;
  652.  
  653.     fprintf(output_file, "%5d,", base[i]);
  654.     }
  655.  
  656.     if (!rflag) outline += 2;
  657.     fprintf(output_file, "\n};\nshort %sgindex[] = {%39d,", symbol_prefix,
  658.         base[2*nstates]);
  659.  
  660.     j = 10;
  661.     for (i = 2*nstates + 1; i < nvectors - 1; i++)
  662.     {
  663.     if (j >= 10)
  664.     {
  665.         if (!rflag) ++outline;
  666.         putc('\n', output_file);
  667.         j = 1;
  668.     }
  669.     else
  670.         ++j;
  671.  
  672.     fprintf(output_file, "%5d,", base[i]);
  673.     }
  674.  
  675.     if (!rflag) outline += 2;
  676.     fprintf(output_file, "\n};\n");
  677.     FREE(base);
  678. }
  679.  
  680.  
  681.  
  682. output_table()
  683. {
  684.     register int i;
  685.     register int j;
  686.  
  687.     ++outline;
  688.     fprintf(code_file, "#define YYTABLESIZE %d\n", high);
  689.     fprintf(output_file, "short %stable[] = {%40d,", symbol_prefix,
  690.         table[0]);
  691.  
  692.     j = 10;
  693.     for (i = 1; i <= high; i++)
  694.     {
  695.     if (j >= 10)
  696.     {
  697.         if (!rflag) ++outline;
  698.         putc('\n', output_file);
  699.         j = 1;
  700.     }
  701.     else
  702.         ++j;
  703.  
  704.     fprintf(output_file, "%5d,", table[i]);
  705.     }
  706.  
  707.     if (!rflag) outline += 2;
  708.     fprintf(output_file, "\n};\n");
  709.     FREE(table);
  710. }
  711.  
  712.  
  713.  
  714. output_check()
  715. {
  716.     register int i;
  717.     register int j;
  718.  
  719.     fprintf(output_file, "short %scheck[] = {%40d,", symbol_prefix,
  720.         check[0]);
  721.  
  722.     j = 10;
  723.     for (i = 1; i <= high; i++)
  724.     {
  725.     if (j >= 10)
  726.     {
  727.         if (!rflag) ++outline;
  728.         putc('\n', output_file);
  729.         j = 1;
  730.     }
  731.     else
  732.         ++j;
  733.  
  734.     fprintf(output_file, "%5d,", check[i]);
  735.     }
  736.  
  737.     if (!rflag) outline += 2;
  738.     fprintf(output_file, "\n};\n");
  739.     FREE(check);
  740. }
  741.  
  742.  
  743. int
  744. is_C_identifier(name)
  745. char *name;
  746. {
  747.     register char *s;
  748.     register int c;
  749.  
  750.     s = name;
  751.     c = *s;
  752.     if (c == '"')
  753.     {
  754.     c = *++s;
  755.     if (!isalpha(c) && c != '_' && c != '$')
  756.         return (0);
  757.     while ((c = *++s) != '"')
  758.     {
  759.         if (!isalnum(c) && c != '_' && c != '$')
  760.         return (0);
  761.     }
  762.     return (1);
  763.     }
  764.  
  765.     if (!isalpha(c) && c != '_' && c != '$')
  766.     return (0);
  767.     while (c = *++s)
  768.     {
  769.     if (!isalnum(c) && c != '_' && c != '$')
  770.         return (0);
  771.     }
  772.     return (1);
  773. }
  774.  
  775.  
  776. output_defines()
  777. {
  778.     register int c, i;
  779.     register char *s;
  780.  
  781.     for (i = 2; i < ntokens; ++i)
  782.     {
  783.     s = symbol_name[i];
  784.     if (is_C_identifier(s))
  785.     {
  786.         fprintf(code_file, "#define ");
  787.         if (dflag) fprintf(defines_file, "#define ");
  788.         c = *s;
  789.         if (c == '"')
  790.         {
  791.         while ((c = *++s) != '"')
  792.         {
  793.             putc(c, code_file);
  794.             if (dflag) putc(c, defines_file);
  795.         }
  796.         }
  797.         else
  798.         {
  799.         do
  800.         {
  801.             putc(c, code_file);
  802.             if (dflag) putc(c, defines_file);
  803.         }
  804.         while (c = *++s);
  805.         }
  806.         ++outline;
  807.         fprintf(code_file, " %d\n", symbol_value[i]);
  808.         if (dflag) fprintf(defines_file, " %d\n", symbol_value[i]);
  809.     }
  810.     }
  811.  
  812.     ++outline;
  813.     fprintf(code_file, "#define YYERRCODE %d\n", symbol_value[1]);
  814.  
  815.     if (dflag && unionized)
  816.     {
  817.     fclose(union_file);
  818.     union_file = fopen(union_file_name, "r");
  819.     if (union_file == NULL) open_error(union_file_name);
  820.     while ((c = getc(union_file)) != EOF)
  821.         putc(c, defines_file);
  822.     fprintf(defines_file, " YYSTYPE;\nextern YYSTYPE %slval;\n",
  823.         symbol_prefix);
  824.     }
  825. }
  826.  
  827.  
  828. output_stored_text()
  829. {
  830.     register int c;
  831.     register FILE *in, *out;
  832.  
  833.     fclose(text_file);
  834.     text_file = fopen(text_file_name, "r");
  835.     if (text_file == NULL)
  836.     open_error(text_file_name);
  837.     in = text_file;
  838.     if ((c = getc(in)) == EOF)
  839.     return;
  840.     out = code_file;
  841.     if (c ==  '\n')
  842.     ++outline;
  843.     putc(c, out);
  844.     while ((c = getc(in)) != EOF)
  845.     {
  846.     if (c == '\n')
  847.         ++outline;
  848.     putc(c, out);
  849.     }
  850.     if (!lflag)
  851.     fprintf(out, line_format, ++outline + 1, code_file_name);
  852. }
  853.  
  854.  
  855. output_debug()
  856. {
  857.     register int i, j, k, max;
  858.     char **symnam, *s;
  859.  
  860.     ++outline;
  861.     fprintf(code_file, "#define YYFINAL %d\n", final_state);
  862.     outline += 3;
  863.     fprintf(code_file, "#ifndef YYDEBUG\n#define YYDEBUG %d\n#endif\n",
  864.         tflag);
  865.     if (rflag)
  866.     fprintf(output_file, "#ifndef YYDEBUG\n#define YYDEBUG %d\n#endif\n",
  867.         tflag);
  868.  
  869.     max = 0;
  870.     for (i = 2; i < ntokens; ++i)
  871.     if (symbol_value[i] > max)
  872.         max = symbol_value[i];
  873.     ++outline;
  874.     fprintf(code_file, "#define YYMAXTOKEN %d\n", max);
  875.  
  876.     symnam = (char **) MALLOC((max+1)*sizeof(char *));
  877.     if (symnam == 0) no_space();
  878.  
  879.     /* Note that it is  not necessary to initialize the element        */
  880.     /* symnam[max].                            */
  881.     for (i = 0; i < max; ++i)
  882.     symnam[i] = 0;
  883.     for (i = ntokens - 1; i >= 2; --i)
  884.     symnam[symbol_value[i]] = symbol_name[i];
  885.     symnam[0] = "end-of-file";
  886.  
  887.     if (!rflag) ++outline;
  888.     fprintf(output_file, "#if YYDEBUG\nchar *%sname[] = {", symbol_prefix);
  889.     j = 80;
  890.     for (i = 0; i <= max; ++i)
  891.     {
  892.     if (s = symnam[i])
  893.     {
  894.         if (s[0] == '"')
  895.         {
  896.         k = 7;
  897.         while (*++s != '"')
  898.         {
  899.             ++k;
  900.             if (*s == '\\')
  901.             {
  902.             k += 2;
  903.             if (*++s == '\\')
  904.                 ++k;
  905.             }
  906.         }
  907.         j += k;
  908.         if (j > 80)
  909.         {
  910.             if (!rflag) ++outline;
  911.             putc('\n', output_file);
  912.             j = k;
  913.         }
  914.         fprintf(output_file, "\"\\\"");
  915.         s = symnam[i];
  916.         while (*++s != '"')
  917.         {
  918.             if (*s == '\\')
  919.             {
  920.             fprintf(output_file, "\\\\");
  921.             if (*++s == '\\')
  922.                 fprintf(output_file, "\\\\");
  923.             else
  924.                 putc(*s, output_file);
  925.             }
  926.             else
  927.             putc(*s, output_file);
  928.         }
  929.         fprintf(output_file, "\\\"\",");
  930.         }
  931.         else if (s[0] == '\'')
  932.         {
  933.         if (s[1] == '"')
  934.         {
  935.             j += 7;
  936.             if (j > 80)
  937.             {
  938.             if (!rflag) ++outline;
  939.             putc('\n', output_file);
  940.             j = 7;
  941.             }
  942.             fprintf(output_file, "\"'\\\"'\",");
  943.         }
  944.         else
  945.         {
  946.             k = 5;
  947.             while (*++s != '\'')
  948.             {
  949.             ++k;
  950.             if (*s == '\\')
  951.             {
  952.                 k += 2;
  953.                 if (*++s == '\\')
  954.                 ++k;
  955.             }
  956.             }
  957.             j += k;
  958.             if (j > 80)
  959.             {
  960.             if (!rflag) ++outline;
  961.             putc('\n', output_file);
  962.             j = k;
  963.             }
  964.             fprintf(output_file, "\"'");
  965.             s = symnam[i];
  966.             while (*++s != '\'')
  967.             {
  968.             if (*s == '\\')
  969.             {
  970.                 fprintf(output_file, "\\\\");
  971.                 if (*++s == '\\')
  972.                 fprintf(output_file, "\\\\");
  973.                 else
  974.                 putc(*s, output_file);
  975.             }
  976.             else
  977.                 putc(*s, output_file);
  978.             }
  979.             fprintf(output_file, "'\",");
  980.         }
  981.         }
  982.         else
  983.         {
  984.         k = strlen(s) + 3;
  985.         j += k;
  986.         if (j > 80)
  987.         {
  988.             if (!rflag) ++outline;
  989.             putc('\n', output_file);
  990.             j = k;
  991.         }
  992.         putc('"', output_file);
  993.         do { putc(*s, output_file); } while (*++s);
  994.         fprintf(output_file, "\",");
  995.         }
  996.     }
  997.     else
  998.     {
  999.         j += 2;
  1000.         if (j > 80)
  1001.         {
  1002.         if (!rflag) ++outline;
  1003.         putc('\n', output_file);
  1004.         j = 2;
  1005.         }
  1006.         fprintf(output_file, "0,");
  1007.     }
  1008.     }
  1009.     if (!rflag) outline += 2;
  1010.     fprintf(output_file, "\n};\n");
  1011.     FREE(symnam);
  1012.  
  1013.     if (!rflag) ++outline;
  1014.     fprintf(output_file, "char *%srule[] = {\n", symbol_prefix);
  1015.     for (i = 2; i < nrules; ++i)
  1016.     {
  1017.     fprintf(output_file, "\"%s :", symbol_name[rlhs[i]]);
  1018.     for (j = rrhs[i]; ritem[j] > 0; ++j)
  1019.     {
  1020.         s = symbol_name[ritem[j]];
  1021.         if (s[0] == '"')
  1022.         {
  1023.         fprintf(output_file, " \\\"");
  1024.         while (*++s != '"')
  1025.         {
  1026.             if (*s == '\\')
  1027.             {
  1028.             if (s[1] == '\\')
  1029.                 fprintf(output_file, "\\\\\\\\");
  1030.             else
  1031.                 fprintf(output_file, "\\\\%c", s[1]);
  1032.             ++s;
  1033.             }
  1034.             else
  1035.             putc(*s, output_file);
  1036.         }
  1037.         fprintf(output_file, "\\\"");
  1038.         }
  1039.         else if (s[0] == '\'')
  1040.         {
  1041.         if (s[1] == '"')
  1042.             fprintf(output_file, " '\\\"'");
  1043.         else if (s[1] == '\\')
  1044.         {
  1045.             if (s[2] == '\\')
  1046.             fprintf(output_file, " '\\\\\\\\");
  1047.             else
  1048.             fprintf(output_file, " '\\\\%c", s[2]);
  1049.             s += 2;
  1050.             while (*++s != '\'')
  1051.             putc(*s, output_file);
  1052.             putc('\'', output_file);
  1053.         }
  1054.         else
  1055.             fprintf(output_file, " '%c'", s[1]);
  1056.         }
  1057.         else
  1058.         fprintf(output_file, " %s", s);
  1059.     }
  1060.     if (!rflag) ++outline;
  1061.     fprintf(output_file, "\",\n");
  1062.     }
  1063.  
  1064.     if (!rflag) outline += 2;
  1065.     fprintf(output_file, "};\n#endif\n");
  1066. }
  1067.  
  1068.  
  1069. output_stype()
  1070. {
  1071.     if (!unionized && ntags == 0)
  1072.     {
  1073.     outline += 3;
  1074.     fprintf(code_file, "#ifndef YYSTYPE\ntypedef int YYSTYPE;\n#endif\n");
  1075.     }
  1076. }
  1077.  
  1078.  
  1079. output_trailing_text()
  1080. {
  1081.     register int c, last;
  1082.     register FILE *in, *out;
  1083.  
  1084.     if (line == 0)
  1085.     return;
  1086.  
  1087.     in = input_file;
  1088.     out = code_file;
  1089.     c = *cptr;
  1090.     if (c == '\n')
  1091.     {
  1092.     ++lineno;
  1093.     if ((c = getc(in)) == EOF)
  1094.         return;
  1095.     if (!lflag)
  1096.     {
  1097.         ++outline;
  1098.         fprintf(out, line_format, lineno, input_file_name);
  1099.     }
  1100.     if (c == '\n')
  1101.         ++outline;
  1102.     putc(c, out);
  1103.     last = c;
  1104.     }
  1105.     else
  1106.     {
  1107.     if (!lflag)
  1108.     {
  1109.         ++outline;
  1110.         fprintf(out, line_format, lineno, input_file_name);
  1111.     }
  1112.     do { putc(c, out); } while ((c = *++cptr) != '\n');
  1113.     ++outline;
  1114.     putc('\n', out);
  1115.     last = '\n';
  1116.     }
  1117.  
  1118.     while ((c = getc(in)) != EOF)
  1119.     {
  1120.     if (c == '\n')
  1121.         ++outline;
  1122.     putc(c, out);
  1123.     last = c;
  1124.     }
  1125.  
  1126.     if (last != '\n')
  1127.     {
  1128.     ++outline;
  1129.     putc('\n', out);
  1130.     }
  1131.     if (!lflag)
  1132.     fprintf(out, line_format, ++outline + 1, code_file_name);
  1133. }
  1134.  
  1135.  
  1136. output_semantic_actions()
  1137. {
  1138.     register int c, last;
  1139.     register FILE *out;
  1140.  
  1141.     fclose(action_file);
  1142.     action_file = fopen(action_file_name, "r");
  1143.     if (action_file == NULL)
  1144.     open_error(action_file_name);
  1145.  
  1146.     if ((c = getc(action_file)) == EOF)
  1147.     return;
  1148.  
  1149.     out = code_file;
  1150.     last = c;
  1151.     if (c == '\n')
  1152.     ++outline;
  1153.     putc(c, out);
  1154.     while ((c = getc(action_file)) != EOF)
  1155.     {
  1156.     if (c == '\n')
  1157.         ++outline;
  1158.     putc(c, out);
  1159.     last = c;
  1160.     }
  1161.  
  1162.     if (last != '\n')
  1163.     {
  1164.     ++outline;
  1165.     putc('\n', out);
  1166.     }
  1167.  
  1168.     if (!lflag)
  1169.     fprintf(out, line_format, ++outline + 1, code_file_name);
  1170. }
  1171.  
  1172.  
  1173. free_itemsets()
  1174. {
  1175.     register core *cp, *next;
  1176.  
  1177.     FREE(state_table);
  1178.     for (cp = first_state; cp; cp = next)
  1179.     {
  1180.     next = cp->next;
  1181.     FREE(cp);
  1182.     }
  1183. }
  1184.  
  1185.  
  1186. free_shifts()
  1187. {
  1188.     register shifts *sp, *next;
  1189.  
  1190.     FREE(shift_table);
  1191.     for (sp = first_shift; sp; sp = next)
  1192.     {
  1193.     next = sp->next;
  1194.     FREE(sp);
  1195.     }
  1196. }
  1197.  
  1198.  
  1199.  
  1200. free_reductions()
  1201. {
  1202.     register reductions *rp, *next;
  1203.  
  1204.     FREE(reduction_table);
  1205.     for (rp = first_reduction; rp; rp = next)
  1206.     {
  1207.     next = rp->next;
  1208.     FREE(rp);
  1209.     }
  1210. }
  1211.